package com.shanshan.wheel.rpc.common.annotation;

import com.shanshan.wheel.rpc.common.provider.RpcServiceProperties;
import com.shanshan.wheel.rpc.common.provider.ServiceProvider;
import com.shanshan.wheel.rpc.common.proxy.RpcClientProxy;
import com.shanshan.wheel.rpc.common.remoting.transport.clent.NettyClient;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * @Description
 * @ClassName RpcBeanPostProcessor
 * @Author 山山大魔王
 * @Date 2022/9/5 22:00
 * @Version 1.0
 */
@Component
@Slf4j
public class RpcBeanPostProcessor implements BeanPostProcessor {

    @Autowired
    private ServiceProvider serviceProvider;

    @Autowired
    private NettyClient nettyClient;


    /**
     * 如果发现该bean被@RpcService标注则注册服务
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean.getClass().isAnnotationPresent(RpcService.class)){
            RpcService annotation = bean.getClass().getAnnotation(RpcService.class);

            RpcServiceProperties properties = RpcServiceProperties.builder()
                    .group(annotation.group())
                    .version(annotation.version())
                    .build();
            serviceProvider.publishService(bean, properties);
        }
        return bean;
    }

    @SneakyThrows
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Field[] declaredFields = bean.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            RpcReference annotation = field.getAnnotation(RpcReference.class);
            if(field.isAnnotationPresent(RpcReference.class)){
                RpcServiceProperties rpcServiceProperties = RpcServiceProperties.builder()
                        .version(annotation.version())
                        .group(annotation.group())
                        .build();

                // 创建动态代理类
                RpcClientProxy rpcClientProxy = new RpcClientProxy(nettyClient, rpcServiceProperties);
                Object proxy = rpcClientProxy.getProxy(field.getType());
                // 开启访问私有变量开关
                field.setAccessible(true);
                // 将bean对象的该字段中的对象替换成代理对象
                field.set(bean, proxy);
            }

        }
        return bean;
    }
}
